package de.carcophan.jimdb.jsf.mb;

import com.flicklib.domain.MovieSearchResult;
import com.flicklib.service.HttpSourceLoader;
import com.flicklib.service.movie.imdb.ImdbParser;
import com.flicklib.service.movie.imdb.ImdbSearch;
import de.carcophan.jimdb.ejb.entites.Movie;
import de.carcophan.jimdb.ejb.entites.Status;
import de.carcophan.jimdb.ejb.entites.User;
import de.carcophan.jimdb.ejb.entites.UserMovies;
import de.carcophan.jimdb.jsf.mb.util.JsfUtil;
import de.carcophan.jimdb.jsf.mb.util.ProxyConfigAppBean;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.ejb.EJBException;
import javax.enterprise.context.SessionScoped;
import javax.enterprise.event.Observes;
import javax.faces.model.DataModel;


import javax.faces.model.ListDataModel;
import javax.inject.Inject;
import javax.inject.Named;

@Named
@SessionScoped
public class SearchController extends Controller {

    private String movieTitle;
    @Inject
    private ProxyConfigAppBean proxyConfig;
    private DataModel<UserMovies> items = null;
    private List<MovieSearchResult> results;

    public SearchController() {
    }

    public String performSearch() throws Exception {
//        ImdbSearch instance = new ImdbSearch(new HttpSourceLoader(proxyConfig), new ImdbParser());
        ImdbSearch instance = new ImdbSearch(new HttpSourceLoader(), new ImdbParser());
        System.out.println(this.movieTitle);
        this.results = instance.getResults(this.movieTitle);
        refreshDataList(null);
        return "secured/index";
    }

    @Override
    public void refreshDataList(@Observes UserMovies um) {
    
        if (this.results != null) {
            ArrayList<UserMovies> movies = new ArrayList<UserMovies>();
            Map<String, UserMovies> merged = new LinkedHashMap<String, UserMovies>();
            for (MovieSearchResult movieSearchResult : results) {
                final Movie movie = new Movie(movieSearchResult);
                final UserMovies userMovies = new UserMovies(movie);
                userMovies.setUser(getAuthenticatedUser());
                movies.add(userMovies);
                merged.put(movie.getIdForSite(), userMovies);
            }
            final Map<String, UserMovies> foundInDB = getUserMoviesFacade().findByImdbIds(merged.keySet(), getAuthenticatedUser().getId());
            for (UserMovies movieInDB : foundInDB.values()) {
                merged.put(movieInDB.getMovie().getIdForSite(), movieInDB);
            }
            setItems(new ListDataModel<UserMovies>(new ArrayList<UserMovies>(merged.values())));
            if (this.movieTitle == null && (movies == null || movies.isEmpty())) {
                this.movieTitle = "";
            }
        }
        sortMovies();
    }

    @Override
    public void saveSelectedMovie() throws Exception {
        setCurrent(getItems().getRowData());
        User user = getAuthenticatedUser();

        Status status = getStatusFacade().findByMovieStatus(getSelectedStatus());
        getCurrent().setUser(user);
        getCurrent().setMovieStatus(status);
        getCurrent().setLastChanged(new Date());
        try {
            Movie findMovieByImdbId = getMovieFacade().findMovieByImdbId(getCurrent().getMovie().getIdForSite());

            if (findMovieByImdbId == null) {
                getMovieFacade().create(getCurrent().getMovie());
                getUserMoviesFacade().create(getCurrent());
            } else {
                getCurrent().setMovie(findMovieByImdbId);
                getUserMoviesFacade().create(getCurrent());
            }
            System.out.println(userMoviesEvent);
            userMoviesEvent.fire(new UserMovies());
        } catch (EJBException e) {
            JsfUtil.addErrorMessage(e.getMessage());
        }
    }

    public String getMovieTitle() {
        return movieTitle;
    }

    public void setMovieTitle(String movieTitle) {
        this.movieTitle = movieTitle;
    }

    @Override
    public DataModel<UserMovies> getItems() {
        return this.items;
    }

    @Override
    public void setItems(DataModel<UserMovies> items) {
        this.items = items;
    }
}
